package com.sunshine.lnuplus.utils

import android.content.*
import androidx.fragment.app.FragmentManager
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.sunshine.lnuplus.R
import com.sunshine.lnuplus.callback.LoginCallBack
import com.sunshine.lnuplus.model.*
import com.sunshine.lnuplus.model.room.CountDown
import com.sunshine.lnuplus.model.room.Lesson
import com.sunshine.lnuplus.model.room.TimetableRepository
import org.jsoup.Jsoup
import org.jsoup.select.Elements
import java.util.*
import kotlin.collections.ArrayList

object LoadLessonUtils{

    private val errorToast = "哎呀，导课出现问题了，请你选择其他方式导课，为了尽快解决这一问题，可以通过关于 -> 联系开发者选项联系一下开发者嘛，谢谢啦"

    fun init(
        repository: TimetableRepository,
        result: Elements,
        loginCallBack: LoginCallBack
    ){
        try {
            repository.deleteAllLesson()
            resolve(result, repository, loginCallBack)
        } catch (e: Exception){
            loginCallBack.onFail("$e $errorToast")
        }

    }

    fun initFileLesson(
        repository: TimetableRepository,
        loginCallBack: LoginCallBack,
        myLessonList: ArrayList<Map<String, String>>
    ){
        try {
            repository.deleteAllLesson()
            resolveFileLesson(repository, loginCallBack, myLessonList)
        }catch (e: Exception){
            loginCallBack.onFail("$e $errorToast")
        }
    }

    fun initSuperLesson(
        repository: TimetableRepository,
        loginCallBack: LoginCallBack,
        context: Context,
        fragmentManager: FragmentManager
    ){
        try {
            repository.deleteAllLesson()
            resolveSuperLesson(repository, loginCallBack)
        }catch (e: Exception){
            var string = "错误信息：$e\n"
            string += SuperData.superLessonList
            TellMeDialog.tellMe(
                context,
                fragmentManager,
                true,
                "${context.resources.getString(R.string.tell_me)}${string}",
                repository)
        }
    }

    fun initBackLesson(
        repository: TimetableRepository
    ){
        try {
            repository.deleteAllLesson()
            resolveBackLesson(repository)
        }catch (e: Exception){

        }
    }

    fun initSchoolLesson(
        repository: TimetableRepository,
        html: String,
        loginCallBack: LoginCallBack,
        context: Context,
        fragmentManager: FragmentManager,
        type: String?
    ){

        try {
            repository.deleteAllLesson()
            when(type){
                "ZF" -> resolveZFLesson(repository, html, loginCallBack)
                "QZ" -> resolveQZLesson(repository, html, loginCallBack)
                "XQZ" -> resolveXQZLesson(repository, html, loginCallBack)
                "ZNMZ" -> resolveZNMZLesson(repository, html, loginCallBack)
                "NJSJJS" -> resolveNJJSSJLesson(repository, html, loginCallBack)
                "XZF" -> resolveXZFLesson(repository, html, loginCallBack)
                "SCGCZYJS" -> resolveSCGCZYJSLesson(repository, html, loginCallBack)
                "GDSYHG" -> resolveGDSYHGLesson(repository, html, loginCallBack)
                else -> loginCallBack.onFail("未解析的教务管理")
            }
        }catch (e: Exception){
            loginCallBack.onFail("")
            var string = "错误信息：$e\n"
            string += html
            TellMeDialog.tellMe(
                context,
                fragmentManager,
                true,
                "${context.resources.getString(R.string.tell_me)}${string}",
                repository)
        }
    }

    fun initQingGuoLesson(
        repository: TimetableRepository,
        lessonList: ArrayList<QingGuoLessonBean>,
        loginCallBack: LoginCallBack,
        context: Context,
        fragmentManager: FragmentManager
    ){
        try {
            repository.deleteAllLesson()
            resolveQingGuoLesson(repository, lessonList, loginCallBack)
        }catch (e: Exception){
            loginCallBack.onFail("")
            var string = "错误信息：$e\n"
            string += lessonList
            TellMeDialog.tellMe(
                context,
                fragmentManager,
                true,
                "${context.resources.getString(R.string.tell_me)}${string}",
                repository)
        }
    }

    private fun resolveQingGuoLesson(repository: TimetableRepository, lessonList: ArrayList<QingGuoLessonBean>, loginCallBack: LoginCallBack) {
        lessonList.forEach {
            val lesson = Lesson(
                it.kcdm,
                it.dayOfWeek,
                it.jcxx.split("-")[0].toInt(),
                "",
                it.jcxx.split("-")[1].toInt(),
                "",
                it.kcmc,
                it.rkjs,
                it.skdd,
                DateUtils.getQGWeeks(it.skzs),
                "0"
            )
            val countDown = CountDown(
                it.kcmc,
                "",
                9999,
                9999,
                9999,
                9999,
                9999,
                "",
                "0"
            )
            repository.insertLesson(lesson)
            repository.insertCountDown(countDown)
        }
        loginCallBack.onSuccess()
    }

    private fun resolveBackLesson(repository: TimetableRepository) {
        InitData.lessonList?.forEach {
            val lesson = Lesson(
                it.lessonId,
                it.dayOfWeek,
                it.start,
                "",
                it.end,
                "",
                it.lessonName,
                it.teacher,
                it.location,
                it.weeks.toString().substring(1, it.weeks.toString().length - 1),
                it.color
            )
            val countDown = CountDown(
                it.lessonName,
                "",
                9999,
                9999,
                9999,
                9999,
                9999,
                "",
                "0"
            )
            repository.insertLesson(lesson)
            repository.insertCountDown(countDown)
        }
    }

    private fun resolveSuperLesson(
        repository: TimetableRepository,
        loginCallBack: LoginCallBack
    ) {
        SuperData.superLessonList.forEach {
            val weeks = it.smartPeriod.replace(" ", ",")
            val lesson = Lesson(
                it.id.toString(),
                it.day,
                it.sectionstart,
                "",
                it.sectionend,
                "",
                it.name,
                it.teacher.replace("*", ""),
                it.locale,
                weeks,
                "0"
            )
            val countDown = CountDown(
                it.name,
                "",
                9999,
                9999,
                9999,
                9999,
                9999,
                "",
                "0"
            )
            repository.insertLesson(lesson)
            repository.insertCountDown(countDown)
        }

        loginCallBack.onSuccess()
    }

    private fun resolve(
        result: Elements,
        repository: TimetableRepository,
        loginCallBack: LoginCallBack
    ) {
        var count = 0 //筛选，小于50用于解析教师，大于50用于解析课程具体信息
        val map: MutableMap<String, String> = HashMap()
        val classInfo = arrayOfNulls<String>(5) //0课程名称，1时间，2地点，3周数，4课号
        for (element in result) {
            if (++count < 50) {
                var teacherInfo: Array<String>
                var info = element.toString()
                info = info
                    .replace("<td bgcolor=\"#EAE2F3\"><p align=\"center\">", "")
                    .replace("<br>", "")
                    .replace("<font color=\"#FF0000\">(.*)</font>".toRegex(), "")
                    .replace("&nbsp;</p></td>", "")
                    .replace(" ", "")
                    .replace("(必修)", "")
                    .replace("(限选)", "")
                    .replace("(任选)", "")
                //判断当前时间是否有课
                if (info != "") {
                    teacherInfo = info.split("/").toTypedArray()
                    map[teacherInfo[0]] = teacherInfo[1]
                }
            } else {
                var info: String = element.toString()
                info = info
                    .replace("<td bgcolor=\"#EAE2F3\"><p align=\"center\">", "")
                    .replace("<br>", "")
                    .replace("<font color=\"#FF0000\">(.*)</font>".toRegex(), "")
                    .replace("&nbsp;</p></td>", "")
                    .replace("全周上课", "1-16")
                    .replace("单周上课", "1,3,5,7,9,11,13,15")
                    .replace("双周上课", "2,4,6,8,10,12,14,16")
                    .replace("周上", "")
                when ((count - 50) % 9) {
                    0 -> classInfo[0] = info
                    2 -> classInfo[4] = info
                    6 -> classInfo[2] = info
                    7 -> classInfo[1] = info
                    8 -> {
                        classInfo[3] = info
                        val time = classInfo[1]?.split("-")
                        val lesson = Lesson(classInfo[4]!!, time?.get(0)!!.toInt(), time[1].toInt() * 2 - 1,"",
                            time[1].toInt() * 2,"",classInfo[0]!!, map[classInfo[0]!!]!!, classInfo[2]!!, classInfo[3]!!, "0")
                        val countDown = CountDown(classInfo[0]!!, "",9999, 9999, 9999, 9999, 9999, "","0")
                        repository.insertLesson(lesson)
                        repository.insertCountDown(countDown)
                    }
                }
            }
        }
        loginCallBack.onSuccess()
    }

    private fun resolveZFLesson(
        repository: TimetableRepository,
        html: String,
        loginCallBack: LoginCallBack
    ){
        val document = Jsoup.parse(html.replace("<font color=\"red\">(.*)</font>".toRegex(), ""))
        val elements = document.select("td[rowspan=\"2\"]")
        if(elements.size == 0){
            loginCallBack.onFail("没有发现课程~")
        }else{
            elements.forEach {
                val zfLesson = it.text().split(" ")
                val count = zfLesson.size / 4
                for(i in 0 until count){
                    val time = zfLesson[1 + i * 4].replace("\\{(.*)\\}".toRegex(), "")
                    val lesson = Lesson(
                        "${Math.random()}",
                        DateUtils.getTodayOfWeekStringToInt(zfLesson[1 + i * 4].substring(0, 2)),
                        time.substring(3, time.length - 1).split(",")[0].toInt(),
                        "",
                        time.substring(3, time.length - 1).split(",")[1].toInt(),
                        "",
                        zfLesson[0 + i * 4],
                        zfLesson[2 + i * 4],
                        zfLesson[3 + i * 4],
                        DateUtils.getZFWeeks(zfLesson[1 + i * 4]),
                        "0"
                    )
                    val countDown = CountDown(
                        zfLesson[0 + i * 4],
                        "",
                        9999,
                        9999,
                        9999,
                        9999,
                        9999,
                        "",
                        "0"
                    )
                    repository.insertLesson(lesson)
                    repository.insertCountDown(countDown)
                }
            }
            loginCallBack.onSuccess()
        }
    }

    private fun resolveXZFLesson(repository: TimetableRepository, html: String, loginCallBack: LoginCallBack) {
        val document = Jsoup.parse(html)
        val elements = document.select("table[id=\"kblist_table\"]")
        if(elements.size == 0){
            loginCallBack.onFail("没有发现课程~")
        }else{
            var count = 0
            var dayOfWeek = 1
            var start = 1
            var end = 1
            var lessonName = ""
            var weeks = ""
            var location = ""
            var teacher = ""
            elements.forEach {
                val lessonList = it.text().split(" ")
                for (i in 7 until lessonList.size){
                    if(lessonList[i].contains("其它课程：")) break
//                    lessonList.forEach {
//                        println(it)
//                    }
                    when(lessonList[i]){
                        "星期一" -> dayOfWeek = 1
                        "星期二" -> dayOfWeek = 2
                        "星期三" -> dayOfWeek = 3
                        "星期四" -> dayOfWeek = 4
                        "星期五" -> dayOfWeek = 5
                        "星期六" -> dayOfWeek = 6
                        "星期日" -> dayOfWeek = 7
                        else -> count++
                    }
                    if(count != 0){
                        if(count == 13){
                            count = 0
                            //println("$dayOfWeek $start $end $lessonName $teacher $location $weeks")
                            val lesson = Lesson(
                                "${Math.random()}",
                                dayOfWeek,
                                start,
                                "",
                                end,
                                "",
                                lessonName,
                                teacher,
                                location,
                                weeks,
                                "0"
                            )
                            val countDown = CountDown(
                                lessonName,
                                "",
                                9999,
                                9999,
                                9999,
                                9999,
                                9999,
                                "",
                                "0"
                            )
                            repository.insertLesson(lesson)
                            repository.insertCountDown(countDown)
                            lessonName = ""
                        }else{
                            when(count){
                                1 -> {
                                    try {
                                        val time = lessonList[i].split("-")
                                        start = time[0].toInt()
                                        end = time[1].toInt()
                                    }catch (e: Exception){
                                        count--
                                    }
                                }
                                2 -> {
                                    if(lessonList[i + 1].contains("周数：")){
                                        lessonName += lessonList[i]
                                    } else{
                                        lessonName = "${lessonList[i]} "
                                        count--
                                    }
                                }
                                3 -> weeks = DateUtils.getXZFWeeks(lessonList[i])
                                5 -> location = lessonList[i].replace("上课地点：", "")
                                6 -> teacher = lessonList[i].replace("教师：", "")
                            }
                        }
                    }
                }
            }
            loginCallBack.onSuccess()
        }
    }

    private fun resolveQZLesson(repository: TimetableRepository, html: String, loginCallBack: LoginCallBack) {
        val document = Jsoup.parse(html)
        val elements = document.getElementById("kbtable").getElementsByTag("tr")
        if(elements.size == 0){
            loginCallBack.onFail("没有发现课程~")
        }else{
            var start = 1
            elements.forEach {
                var dayOfWeek = 1
                val jieLessons = it.getElementsByTag("td")
                if(jieLessons.size != 0){
                    jieLessons.forEach {jieLesson ->
                        val temp = jieLesson.select("div[class=\"kbcontent\"]").toString().split("<br>---------------------")
                        val lessonHtmls = jieLesson.select("div[class=\"kbcontent\"]").text().split("---------------------")
                        //println(lessonHtmls)
                        for (i in lessonHtmls.indices){
                            val lessonDoc = Jsoup.parse(temp[i])
                            val lessonName = lessonHtmls[i].split(" ")[0]
                            if(lessonName.isEmpty()) continue
                            val teacher = lessonDoc.select("font[title=\"老师\"]").text()
                            val weeks = DateUtils.getQZWeeks(lessonDoc.select("font[title=\"周次(节次)\"]").text())
                            val location = lessonDoc.select("font[title=\"教室\"]").text()
                            val lesson = Lesson(
                                "${Math.random()}",
                                dayOfWeek,
                                start,
                                "",
                                start + 1,
                                "",
                                lessonName,
                                teacher,
                                location,
                                weeks,
                                "0"
                            )
                            val countDown = CountDown(
                                lessonName,
                                "",
                                9999,
                                9999,
                                9999,
                                9999,
                                9999,
                                "",
                                "0"
                            )
                            repository.insertLesson(lesson)
                            repository.insertCountDown(countDown)
                        }
                        dayOfWeek++
                        if(dayOfWeek > 7) dayOfWeek = 1
                    }
                    start += 2
                }
            }
            loginCallBack.onSuccess()
        }
    }

    private fun resolveXQZLesson(repository: TimetableRepository, html: String, loginCallBack: LoginCallBack) {
        val document = Jsoup.parse(html)
        val elements = document.select("td").select("div[class=\"kbcontent\"]")
        if(elements.size == 0){
            loginCallBack.onFail("没有发现课程~")
        }else{
            var i = 1
            elements.forEach {
                val lessonJieString = it.text().split(" --------------------- ")
                if(lessonJieString[0].isNotEmpty()){
                    lessonJieString.forEach {lessonJie ->
                        val lessonString = lessonJie.split(" ")
                        val start = DateUtils.getQZTimeStart(lessonString[2])
                        val end = DateUtils.getQZTimeEnd(lessonString[2])
                        val lesson = Lesson(
                            "${Math.random()}",
                            i % 7,
                            (i - 1) / 7 + 1,
                            "",
                            (i - 1) / 7 + 1,
                            "",
                            lessonString[0],
                            lessonString[1],
                            lessonString[3],
                            DateUtils.getXQZWeeks(lessonString[2]),
                            "0"
                        )
                        val countDown = CountDown(
                            lessonString[0],
                            "",
                            9999,
                            9999,
                            9999,
                            9999,
                            9999,
                            "",
                            "0"
                        )
                        repository.insertLesson(lesson)
                        repository.insertCountDown(countDown)
                    }
                }
                i++
            }
            loginCallBack.onSuccess()
        }
    }

    private fun resolveZNMZLesson(repository: TimetableRepository, html: String, loginCallBack: LoginCallBack){
        val document = Jsoup.parse(html)
        val elements = document.select("table[class=\"CourseFormTable\"]").select("td")
        if(elements.size == 0){
            loginCallBack.onFail("没有发现课程~")
        }else{
            var dayOfWeek = 1
            for (it in elements){
                val lessonString = it.text().split(" ")
                if(it.text().contains("未安排时间课程")) break
                if(it.text().isBlank()){
                    dayOfWeek++
                }else{
                    if(it.text()[0].toString() == "第" && (it.text()[2].toString() == "节" || it.text()[3].toString() == "节")){
                        dayOfWeek = 1
                    }else{
                        val time = DateUtils.getZNMZTime(lessonString[2])
                        val lesson = Lesson(
                            "${Math.random()}",
                            dayOfWeek,
                            time[0],
                            "",
                            time[1],
                            "",
                            lessonString[0],
                            lessonString[3],
                            "${lessonString[4]} ${lessonString[5]}",
                            DateUtils.getZNMZWeeks(lessonString[1]),
                            "0"
                        )
                        val countDown = CountDown(
                            lessonString[0],
                            "",
                            9999,
                            9999,
                            9999,
                            9999,
                            9999,
                            "",
                            "0"
                        )
                        repository.insertLesson(lesson)
                        repository.insertCountDown(countDown)
                        dayOfWeek++
                    }
                }
            }
        }
        loginCallBack.onSuccess()
    }

    private fun resolveNJJSSJLesson(repository: TimetableRepository, html: String, loginCallBack: LoginCallBack) {
        val document = Jsoup.parse(html)
        val elements = document.select("td[align=\"left\"]")
        var lessonList: List<List<String>>? = null
        if(elements.size == 0){
            loginCallBack.onFail("没有发现课程")
        }else{
            var count = 1
            var lessonName = ""
            elements.forEach {
                when(count++){
                    1 -> lessonName = it.text()
                    2 -> {
                        lessonList = DateUtils.resloveNJSJJSTime(it.text())
                    }
                    4 -> {
                        lessonList?.forEach {lesson ->
                            val myLesson = Lesson(
                                "${Math.random()}",
                                lesson[2].toInt(),
                                lesson[3].toInt(),
                                "",
                                lesson[4].toInt(),
                                "",
                                lessonName,
                                it.text(),
                                lesson[0],
                                lesson[1],
                                "0"
                            )
                            repository.insertLesson(myLesson)
                        }
                        if(lessonList != null && lessonList!!.isNotEmpty()){
                            val countDown = CountDown(
                                lessonName,
                                "",
                                9999,
                                9999,
                                9999,
                                9999,
                                9999,
                                "",
                                "0"
                            )
                            repository.insertCountDown(countDown)
                        }
                        count = 1
                    }
                }
            }
            loginCallBack.onSuccess()
        }
    }

    private fun resolveSCGCZYJSLesson(repository: TimetableRepository, html: String, loginCallBack: LoginCallBack) {
        val document = Jsoup.parse(html)
        val elements = document.select("td[valign=\"top\"]")
        if(elements.size == 0){
            loginCallBack.onFail("没有发现课程~")
        }else{
            var count = 0
            var start = 1
            elements.forEach {
                count++
                if (it.text().isNotEmpty()){
                    var lessonName = ""
                    var end = 1
                    var teacher = ""
                    var location = ""
                    var weeks = ""
                    var houyi = 0
                    val lesson = it.text().split(" ")
                    while (!lesson[1 + houyi].contains("节)")){
                        houyi++
                    }
                    for (i in 0 .. houyi){
                        lessonName += lesson[i]
                    }
                    when{
                        lesson[1 + houyi].contains("单周") -> {
                            end = start + lesson[1 + houyi].replace("(单周", "").replace("节)", "").toInt() / 2 - 1
                            val time = lesson[4 + houyi].split("-")
                            for (i in time[0].toInt()..time[1].toInt()){
                                if(i % 2 != 0) weeks += "$i,"
                            }
                        }
                        lesson[1 + houyi].contains("双周") -> {
                            end = start + lesson[1 + houyi].replace("(双周", "").replace("节)", "").toInt() / 2 - 1
                            val time = lesson[4 + houyi].split("-")
                            for (i in time[0].toInt()..time[1].toInt()){
                                if(i % 2 == 0) weeks += "$i,"
                            }
                        }
                        else ->{
                            end = start + lesson[1 + houyi].replace("(", "").replace("节)", "").toInt() / 2 - 1
                            val time = lesson[4 + houyi].split("-")
                            if(time.size == 1) weeks += "${time[0]},"
                            else{
                                for (i in time[0].toInt()..time[1].toInt()){
                                    weeks += "$i,"
                                }
                            }
                        }
                    }
                    weeks = weeks.substring(0, weeks.length - 1)
                    teacher = lesson[2 + houyi]
                    location= lesson[3 + houyi]
                    //println("$count $start $end $lessonName $teacher $location $weeks")
                    val lessonDB = Lesson(
                        "${Math.random()}",
                        count,
                        start,
                        "",
                        end,
                        "",
                        lessonName,
                        teacher,
                        location,
                        weeks,
                        "0"
                    )
                    val countDown = CountDown(
                        lessonName,
                        "",
                        9999,
                        9999,
                        9999,
                        9999,
                        9999,
                        "",
                        "0"
                    )
                    repository.insertLesson(lessonDB)
                    repository.insertCountDown(countDown)
                }

                if (count == 7){
                    start++
                    count = 0
                }
            }
            loginCallBack.onSuccess()
        }
    }

    private fun resolveGDSYHGLesson(repository: TimetableRepository, html: String, loginCallBack: LoginCallBack) {
        val json = html.substringAfter("var kbxx = ").substringBefore(";")
        if(json.isEmpty()) {
            loginCallBack.onFail("没有发现课程~")
        }else{
            val timetableList= Gson().fromJson<List<GDSYHGBean>>(json, object : TypeToken<List<GDSYHGBean>>() {}.type)
            timetableList.forEach {
                val time = it.jcdm2.split(",")
                val start = time[0].toInt()
                val end = if(time.size == 2) time[1].toInt() else start
                val lessonDB = Lesson(
                    it.kcbh,
                    it.xq.toInt(),
                    start,
                    "",
                    end,
                    "",
                    it.kcmc,
                    it.teaxms,
                    it.jxcdmcs,
                    it.zcs,
                    "0"
                )
                val countDown = CountDown(
                    it.kcmc,
                    "",
                    9999,
                    9999,
                    9999,
                    9999,
                    9999,
                    "",
                    "0"
                )
                repository.insertLesson(lessonDB)
                repository.insertCountDown(countDown)
            }
            loginCallBack.onSuccess()
        }
    }

    private fun resolveFileLesson(
        repository: TimetableRepository,
        loginCallBack: LoginCallBack,
        myLessonList: ArrayList<Map<String, String>>
    ) {
        myLessonList.forEach {
            val dayOfWeek = DateUtils.getTodayOfWeekStringToInt(it["dayOfWeek"]!!)
            val jie = DateUtils.getJieToStart(it["jie"]!!)
            val weeks = DateUtils.getWeeks(it["weeks"]!!).replace("周上", "")
            val lesson = Lesson(
                it["lessonId"]!!,
                dayOfWeek,
                jie,
                "",
                jie,
                "",
                it["lessonName"]!!,
                it["teacher"]!!,
                it["location"]!!,
                weeks,
                "0"
            )
            val countDown = CountDown(
                it["lessonName"]!!,
                "",
                9999,
                9999,
                9999,
                9999,
                9999,
                "",
                "0"
            )
            repository.insertLesson(lesson)
            repository.insertCountDown(countDown)
        }
        loginCallBack.onSuccess()
    }
}